////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2017 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file  camxfd4xhwutils.cpp
/// @brief FD utility class
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#include "camxdebugprint.h"
#include "camxdefs.h"
#include "camxfd4xhwutils.h"
#include "camxosutils.h"
#include "camxtypes.h"

#include "titan170_fd_wrapper.h"

CAMX_NAMESPACE_BEGIN

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// FD4xHwUtils::GetPoseAngleFromRegValue
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
INT32 FD4xHwUtils::GetPoseAngleFromRegValue(
    UINT32 poseRegValue)
{
    INT32   pose;

    switch (poseRegValue)
    {
        case FDHwPoseFront:
            pose = 0;
            break;
        case FDHwPoseRightDiagonal:
            pose = 45;
            break;
        case FDHwPoseRight:
            pose = 90;
            break;
        case FDHwPoseLeftDiagonal:
            pose = -45;
            break;
        case FDHwPoseLeft:
            pose = -90;
            break;
        default:
            pose = 0;
            CAMX_LOG_WARN(CamxLogGroupFD, "Invalid pose = %d, return default", poseRegValue);
            break;
    }

    return pose;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// FD4xHwUtils::CalculatePyramidBufferSize
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CamxResult FD4xHwUtils::CalculatePyramidBufferSize(
    UINT32  width,
    UINT32  height,
    UINT32* pSize)
{
    CamxResult  result = CamxResultSuccess;

    if ((FDVGAWidth == width) && (FDVGAHeight == height))
    {
        *pSize = FDPyramidBufferSizeVGA;
    }
    else if ((FDQVGAWidth == width) && (FDQVGAHeight == height))
    {
        *pSize = FDPyramidBufferSizeQVGA;
    }
    else if ((FDWQVGAPlusWidth == width) && (FDWQVGAPlusHeight == height))
    {
        *pSize = FDPyramidBufferSizeWQVGAPlus;
    }
    else if ((FDWVGAPlusWidth == width) && (FDWVGAPlusHeight == height))
    {
        *pSize = FDPyramidBufferSizeWVGAPlus;
    }
    else
    {
        CAMX_LOG_ERROR(CamxLogGroupFD, "Invalid FD frame dimensions [%d, %d]", width, height);
        result = CamxResultEUnsupported;
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// FD4xHwUtils::UpdateFDHwCondValue
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CamxResult FD4xHwUtils::UpdateFDHwCondValue(
    UINT32          hwMajorVersion,
    BOOL            enableHwFP,
    UINT32          minFaceSize,
    INT32           referenceOrientation,
    FDSearchAngle   angle,
    UINT32*         pReg)
{
    CamxResult  result          = CamxResultSuccess;
    UINT32      detectionDir    = 0;

    if ((-1 == referenceOrientation) || (FDAngleAll == angle))
    {
        detectionDir = FDHwDirectionAll;
    }
    else
    {
        if (referenceOrientation < 45)
        {
            switch (angle)
            {
                case FDAngle45:  detectionDir = FDHwUpwardDirection45;  break;
                case FDAngle135: detectionDir = FDHwUpwardDirection135; break;
                default:         detectionDir = FDHwDirectionAll;       break;
            }
        }
        else if (referenceOrientation < 135)
        {
            switch (angle)
            {
                case FDAngle45:  detectionDir = FDHwRightDirection45;  break;
                case FDAngle135: detectionDir = FDHwRightDirection135; break;
                default:         detectionDir = FDHwDirectionAll;      break;
            }
        }
        else if (referenceOrientation < 225)
        {
            switch (angle)
            {
                case FDAngle45:  detectionDir = FDHwDownwardDirection45;  break;
                case FDAngle135: detectionDir = FDHwDownwardDirection135; break;
                default:         detectionDir = FDHwDirectionAll;         break;
            }
        }
        else
        {
            switch (angle)
            {
                case FDAngle45:  detectionDir = FDHwLeftDirection45;  break;
                case FDAngle135: detectionDir = FDHwLeftDirection135; break;
                default:         detectionDir = FDHwDirectionAll;     break;
            }
        }
    }

    *pReg = detectionDir << FD_WRAPPER_FD_A_FD_COND_DIR_SHIFT;

    if (FDMinFacePixels0 >= minFaceSize)
    {
        *pReg |= FDMinFaceSize0;
    }
    else if (FDMinFacePixels1 >= minFaceSize)
    {
        *pReg |= FDMinFaceSize1;
    }
    else if (FDMinFacePixels2 >= minFaceSize)
    {
        *pReg |= FDMinFaceSize2;
    }
    else if (FDMinFacePixels3 >= minFaceSize)
    {
        *pReg |= FDMinFaceSize3;
    }
    else
    {
        *pReg |= FDMinFaceSize3;
        CAMX_LOG_ERROR(CamxLogGroupFD, "Min face size %d not supported by HW, set to default", minFaceSize);
    }

    if ((FDHWMajorVersion5 == hwMajorVersion) && (FALSE == enableHwFP))
    {
        *pReg |= FDHWFPSetOffBit;
    }

    return result;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// FD4xHwUtils::UpdateFDHwImageValue
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
CamxResult FD4xHwUtils::UpdateFDHwImageValue(
    UINT32  width,
    UINT32  height,
    UINT32* pReg)
{
    CamxResult  result = CamxResultSuccess;

    if ((FDQVGAWidth == width) && (FDQVGAHeight == height))
    {
        *pReg = FDInputImageQVGA;
    }
    else if ((FDVGAWidth == width) && (FDVGAHeight == height))
    {
        *pReg = FDInputImageVGA;
    }
    else if ((FDWQVGAPlusWidth == width) && (FDWQVGAPlusHeight == height))
    {
        *pReg = FDInputImageWQVGAPlus;
    }
    else if ((FDWVGAPlusWidth == width) && (FDWVGAPlusHeight == height))
    {
        *pReg = FDInputImageWVGAPlus;
    }
    else
    {
        CAMX_LOG_ERROR(CamxLogGroupFD, "Invalid FD frame dimensions [%d, %d]", width, height);
        result = CamxResultEUnsupported;
    }

    return result;
}

CAMX_NAMESPACE_END